from dash import Input, Output, State, callback_context, no_update
import dash_bootstrap_components as dbc
from server import server
from models import RepairRecord
from dash import Input, Output, State, callback_context, no_update, ALL,html
from models import db, RepairRecord
from datetime import datetime
import dash
import base64
import os,time
from modules.generatelogs.generatelogs import write_repair_log
from flask import session
from dash import Output, Input, State, ctx

def register_callbacks(dash_app):
    

    # 打开维修响应模态窗口并带出信息
    @dash_app.callback(
        Output("repair-respond-modal", "is_open"),
        Output("repair-respond-info", "children"),
        Output("repair-respond-person", "value"),
        Output("repair-respond-company", "value"),
        Output("repair-respond-expected-date", "date"),
        Output("repair-respond-remarks", "value"),
        Output("repair-respond-alert", "is_open"),
        Output("repair-respond-alert", "children"),
        Input("repair-respond-button", "n_clicks"),  # 只监听左下角按钮
        State("repair-records-table", "data"),
        State("repair-details-record-id-store", "data"),  # 需要知道当前选中的记录id
        prevent_initial_call=True
    )
    def open_repair_respond_modal(n_clicks, table_data, record_id):
        # print(f'callbacks5 p100 n_clicks:{n_clicks},record_id:{record_id}')
        if not n_clicks or not record_id:
            return dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update, False, ""
        # 查找该条记录
        record = next((r for r in table_data if r["id"] == record_id), None)
        if not record:
            return dash.no_update, "未找到维修记录", "", "", None, "", True, "未找到维修记录"
        from models import Product  # 确保导入 Product
        ctx = callback_context
        if not ctx.triggered:
            raise dash.exceptions.PreventUpdate
        # 找到被点击的按钮index
        btn_id = ctx.triggered[0]["prop_id"].split(".")[0]
        try:
            record_id = int(record_id)
        except Exception as e:
            print(f'callbacks5 P117 ctx.triggered:{ctx.triggered},error:{e},')
            # 直接使用传入的record_id参数
        if not record_id:
            return no_update, no_update, no_update, no_update, no_update, no_update, True, "无法识别维修记录ID"
            
        # 查找该条记录
        record = next((r for r in table_data if r["id"] == record_id), None)
        # print(f'callbacks5 P121 record:{record}')
        if not record:
            return no_update, no_update, no_update, no_update, no_update, no_update, True, "未找到维修记录"
        # 用 product_id 查 Product 表
        product_id = record.get("product_id")
        # print(f'callbacks2 P37 product_id:{product_id},record:{record}')
        product_info = None
        print(f'callbacks5 P127 product_id:{product_id}')
        if product_id:
            product = db.session.query(Product).filter_by(id=product_id).first()
            if product:
                product_info = [
                    # html.Div(f"设备详细信息："),
                    # html.Div(f"设备ID: {product.id}"),
                    # html.Div(f"设备名称: {product.product_name}"),
                    html.Div(f"设备编号: {product.product_code}"),
                    html.Div(f"品牌: {getattr(product, 'manufacturer', '')}"),
                    html.Div(f"型号: {getattr(product, 'model', '')}"),
                    # html.Div(f"机构: {getattr(product, 'org_short_name_c', '')}"),
                    # html.Div(f"科室: {getattr(product, 'department_name', '')}"),
                    # html.Div(f"采购日期: {product.purchase_date.strftime('%Y-%m-%d') if product.purchase_date else ''}"),
                    # html.Div(f"价格: {product.price}"),
                    html.Div(f"运行状态: {getattr(product, 'running_status', '')}"),
                ]
            else:
                product_info = [html.Div("未找到设备详细信息")]
        else:
            product_info = [html.Div("无设备ID，无法查询设备信息")]

        # 展示信息（维修单信息 + 设备详细信息）
        info = html.Div(
            dbc.Row([
                dbc.Col(html.Div(f"维修单号: {record['id']}", className='text-nowrap'), width=3),
                dbc.Col(html.Div(f"设备ID: {record.get('product_id', '')}"), width=3),
                dbc.Col(html.Div(f"设备名称: {record.get('product_name', '')}"), width=3),
                dbc.Col(html.Div(f"机构: {record.get('org_shortname', '')}"), width=3),
                
                dbc.Col(html.Div(f"科室: {record.get('department_name', '')}"), width=3),
                dbc.Col(html.Div(f"报修人: {record.get('repair_caller', '')}"), width=3),
                dbc.Col(html.Div(f"报修时间: {record.get('report_date', '')}"), width=3),
                dbc.Col(html.Div(f"当前状态: {record.get('repair_status', '')}"), width=3),
                
                dbc.Col(html.Div(f"故障描述: {record.get('fault_description', '')}"), width=12),
                
                # dbc.Col([
                #     html.Hr(),
                #     *product_info
                # ], width=12)
            ], className="g-2"),
            style={
                "backgroundColor": "#3498db",
                "padding": "20px",
                "borderRadius": "10px",
                "color": "white",
                "boxShadow": "0 4px 8px rgba(0,0,0,0.2)",
                "marginTop": "20px"
            }
        )
        return True, info, "", "", None, "", False, ""

    # 关闭模态窗口
    @dash_app.callback(
        Output("repair-respond-modal", "is_open", allow_duplicate=True),
        Input("repair-respond-cancel", "n_clicks"),
        prevent_initial_call=True
    )
    def close_repair_respond_modal(n_cancel):
        if n_cancel:
            return False
        return no_update

    # 提交维修响应
    @dash_app.callback(
        Output('repair-refresh-flag-answer', 'data'),
        Output("repair-respond-modal", "is_open", allow_duplicate=True),
        Output("repair-respond-alert", "is_open", allow_duplicate=True),
        Output("repair-respond-alert", "children", allow_duplicate=True),
        Output("repair-complete-button", "disabled", allow_duplicate=True),
        Output("repair-respond-button", "disabled", allow_duplicate=True),
        Input("repair-respond-confirm", "n_clicks"),
        State("repair-respond-person", "value"),
        State("repair-respond-company", "value"),
        State("repair-respond-expected-date", "date"),
        State("repair-respond-remarks", "value"),
        State("repair-respond-info", "children"),
        State("repair-details-record-id-store", "data"), # 获取当前记录ID
        State("repair-respond-repairtype", "value"), # 新增：获取维修类型的值
        prevent_initial_call=True
    )
    def submit_repair_respond(n_submit, person, company, expected_date, remarks, info_children, record_id, repair_type_value):
        if not n_submit:
            raise dash.exceptions.PreventUpdate
        try:
            
            children = info_children.get("props", {}).get("children", []) if isinstance(info_children, dict) else info_children
            for child in children:
                text = ""
                if isinstance(child, dict):
                    text = child.get("props", {}).get("children", "")
                elif isinstance(child, str):
                    text = child
                if "维修单号" in text:
                    record_id = int(text.split(":")[1].strip())
                    break
            if not record_id:
                return dash.no_update,dash.no_update, True, "无法获取维修单号", dash.no_update, dash.no_update
        except Exception as e:
            return dash.no_update, dash.no_update,True, "无法解析维修单号", dash.no_update, dash.no_update
        if not person or not company :
            return dash.no_update,dash.no_update, True, "请填写所有必填项", dash.no_update, dash.no_update
        record = db.session.query(RepairRecord).filter_by(id=record_id).first()
        if not record:
            return dash.no_update,dash.no_update, True, "未找到维修记录", dash.no_update, dash.no_update
        record.repair_person = person
        record.repair_company = company
        try:
            record.expected_completion_date = datetime.strptime(expected_date, "%Y-%m-%d").date()
        except Exception as e:
            pass
        record.remarks = remarks
        record.repair_status = "维修中"
        record.repair_answer_date = datetime.now() # 新增：记录响应时间
        record.repair_type = repair_type_value # 新增：记录维修类型
        db.session.commit()
        from flask import session
        from models import User
        user_id = session.get("user_id")
        if user_id:
            user = User.query.get(user_id)
            username = user.username if user else "匿名用户"
        else:
            username = "匿名用户"
        write_repair_log(
            action="维修响应",
            username=username,
            device_id=record.product_id,
            record_id=record.id,
            message=f"维修人员：{person},维修公司: {company}, 预计完成: {expected_date}, 备注: {remarks}, 维修类型: {repair_type_value}"
        )
        # 关键：返回一个带时间戳的字典，确保每次都不同，触表格刷新
        return {"refresh": True, "ts": time.time()}, False, False, "", True, True

    @dash_app.callback(
        Output("upload-proof-modal-2", "is_open"),
        Output("upload-proof-alert", "is_open"),
        Output("upload-proof-alert", "children"),
        Output("proof-preview-refresh", "data"),  # 新增
        Input("upload-proof-btn", "n_clicks"),
        Input("upload-proof-cancel", "n_clicks"),
        Input("upload-proof", "contents"),
        State("repair-details-record-id-store", "data"),
        State("upload-proof", "filename"),
        prevent_initial_call=True
    )
    def handle_upload_proof(open_click, cancel_click, upload_contents, record_id, upload_filename):
        # print(f'callbacks5 p209 open_click:{open_click},cancel_click:{cancel_click},record_id:{record_id},upload_filename:{upload_filename}')
        import time
        ctx = dash.callback_context
        if not ctx.triggered:
            raise dash.exceptions.PreventUpdate
        trigger = ctx.triggered[0]["prop_id"].split(".")[0]
        
        
        # print(f"完整触发信息: {ctx.triggered} : p217完整触发信息结束")
        print(f"p218触发器: {trigger}")
        
        if trigger == "upload-proof-cancel":
            # 强制返回四元组并清除残留状态
            return (
                False,  # is_open
                True,  # alert_is_open
                "工单上传成功，请点左上角刷新浏览器页面关闭此窗口",     # alert_content
                str(time.time()) + '_force'  # 带强制刷新的时间戳
            )
        if trigger == "upload-proof-btn":
            print("执行打开操作")
            import time
            return True, False, "工单支持重新上传", str(time.time())
        if trigger == "upload-proof" and upload_contents and record_id:
            # 解析图片内容
            content_type, content_string = upload_contents.split(',')
            img_data = base64.b64decode(content_string)
            # 构造保存路径
            save_dir = "static/proofs"
            os.makedirs(save_dir, exist_ok=True)
            save_path = os.path.join("static","proofs", f"工单{record_id}.jpg")
            with open(save_path, "wb") as f:
                f.write(img_data)
            # 更新数据库
            record = db.session.query(RepairRecord).filter_by(id=record_id).first()
            if record:
                record.proof = save_path
                db.session.commit()
                # 新增：写入日志
                from flask import session
                from models import User
                user_id = session.get("user_id")
                if user_id:
                    user = User.query.get(user_id)
                    username = user.username if user else "匿名用户"
                else:
                    username = "匿名用户"
                write_repair_log(
                    action="上传工单",
                    username=username,
                    device_id=record.product_id,
                    record_id=record_id,
                    message=f"工单上传人：{username}，上传成功"
                )
                
                return False, True, "上传成功！", str(time.time())  # 修改这里：第一个参数改为False
            else:
                # 新增：写入日志
                from flask import session
                from models import User
                user_id = session.get("user_id")
                if user_id:
                    user = User.query.get(user_id)
                    username = user.username if user else "匿名用户"
                else:
                    username = "匿名用户"
                write_repair_log(
                    action="上传工单",
                    username=username,
                    device_id=record.product_id,
                    record_id=record_id,
                    message=f"工单上传人：{username}，上传失败"
                )
                return dash.no_update, True, "未找到维修记录", dash.no_update  # 修改这里：第一个参数改为False
        return dash.no_update, dash.no_update, dash.no_update, dash.no_update

    
    @dash_app.callback(
        Output("proof-preview-area", "children"),
        Input("repair-details-record-id-store", "data"),
        Input("proof-preview-refresh", "data"),
    )
    def update_proof_preview(record_id, refresh_flag):
        if not record_id:
            return ""
        record = db.session.query(RepairRecord).filter_by(id=record_id).first()
        if not record or not record.proof:
            return ""
        ts = refresh_flag or ""
        file_url = "/" + record.proof.replace("\\", "/")
        if ts:
            file_url_with_ts = f"{file_url}?v={ts}"
        else:
            file_url_with_ts = file_url
        # 用 splitext 判断类型，忽略参数
        ext = os.path.splitext(file_url)[-1].lower()
        if ext in [".jpg", ".jpeg", ".png", ".gif"]:
            preview = html.Img(src=file_url_with_ts, style={"maxWidth": "100%", "margin": "10px 0"})
        elif ext == ".pdf":
            preview = html.Iframe(src=file_url_with_ts, style={"width": "100%", "height": "400px", "margin": "10px 0"})
        else:
            preview = html.Div("暂不支持预览该文件类型")
        download_btn = html.A("下载工单", href=file_url_with_ts, download=True, target="_blank", className="btn btn-primary mt-2")
        return html.Div([preview, download_btn])

        # 重置按钮
    @dash_app.callback(
        Output('repair-org-filter', 'value', allow_duplicate=True),
        Output('repair-dept-filter', 'value', allow_duplicate=True),
        Output('repair-id-filter', 'value', allow_duplicate=True),
        Output('repair-status-filter', 'value', allow_duplicate=True),
        Output('repair-date-filter', 'start_date', allow_duplicate=True),
        Output('repair-date-filter', 'end_date', allow_duplicate=True),
        Output('repair-keyword-filter', 'value', allow_duplicate=True),
        Output('repair-person-filter', 'value', allow_duplicate=True),
        Output('repair-caller-filter', 'value', allow_duplicate=True),
        Input('repair-reset-button', 'n_clicks'),
        prevent_initial_call=True
    )
    def reset_filters(n_clicks):
        if n_clicks:
            return None, None, None, None, None, None, "", [], []
        return dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update, dash.no_update


    # @dash_app.callback(
    #     Output('repair-details-record-id-store', 'data'),
    #     Input('repair-records-table', 'selected_rows'),
    #     State('repair-records-table', 'data')
    # )
    # def update_selected_record_id(selected_rows, table_data):
    #     if selected_rows and table_data:
    #         return table_data[selected_rows[0]].get('id')
    #     return None

    @dash_app.callback(
        Output("repair-records-table", "style_data_conditional"),
        Input("repair-records-table", "active_cell"),
        prevent_initial_call=True
    )
    def highlight_active_row(active_cell):
        if not active_cell:
            return []
        row = active_cell["row"]
        return [
            {
                "if": {"row_index": row},
                "color": "orange"
            }
        ]

    # # 假设按钮id为'repair-respond-button'，表格id为'repair-records-table'
    # @dash_app.callback(
    #     [Output('repair-records-table', 'data', allow_duplicate=True),
    #      Output('repair-respond-button', 'disabled', allow_duplicate=True),
    #      Output('repair-complete-button', 'disabled', allow_duplicate=True),
    #      Output('upload-proof-btn', 'disabled', allow_duplicate=True)],
    #     [Input('repair-respond-button', 'n_clicks')],
    #     [Input('repair-records-table', 'active_cell'),
    #      State('repair-records-table', 'data')],
    #     allow_duplicate=True,
    #     prevent_initial_call='initial_duplicate'
    # )
    # def refresh_table_and_buttons(n_clicks, active_cell, table_data):
    #     def get_latest_data():
    #         from models import RepairRecord
    #         from server import db
    #         records = db.session.query(RepairRecord).filter(RepairRecord.is_active == True).order_by(RepairRecord.report_date.desc()).all()
    #         data = []
    #         for r in records:
    #             data.append({
    #                 'id': r.id,
    #                 'product_id': r.product_id,
    #                 'product_name': r.product_name,
    #                 'org_shortname': r.org_shortname_c,
    #                 'department_name': r.department_name,
    #                 'fault_description': r.fault_description,
    #                 'report_date': r.report_date.strftime('%Y-%m-%d %H:%M:%S') if r.report_date else '',
    #                 'repair_status': r.repair_status,
    #                 'actual_completion_date':r.actual_completion_date,
    #                  'repair_duration': r.repair_duration,

    #                 'repair_person': r.repair_person,
    #                 'repair_company': r.repair_company,
    #                 'repair_type': r.repair_type,
    #                'repair_content': r.repair_content,
    #                 'repair_cost': r.repair_cost,
    #                 'parts_replaced': r.parts_replaced,
    #                 'repair_result': r.repair_result,
    #             })
    #         # 若无数据，返回结构完整的空行，保证DataTable分页器和列头正常显示
    #         if not data:
    #             data = [{
    #                 'id': '',
    #                 'product_id': '',
    #                 'product_name': '',
    #                 'org_shortname': '',
    #                 'department_name': '',
    #                 'fault_description': '',
    #                 'report_date': '',
    #                 'repair_status': '',
    #                 'repair_person': ''
    #             }]
    #         return data
    #     new_data = get_latest_data()
    #     if active_cell is not None:
    #         row = active_cell['row']
    #         if 0 <= row < len(new_data):
    #             row_data = new_data[row]
    #             repair_status = row_data.get('repair_status', '')
    #             disabled1 = repair_status != '待响应'
    #             disabled2 = repair_status != '维修中'
    #             disabled3 = repair_status != '待上传'
    #         else:
    #             disabled1 = disabled2 = disabled3 = True
    #     else:
    #         disabled1 = disabled2 = disabled3 = True
    #     return new_data, disabled1, disabled2, disabled3
         